package crawler

import (
	"fmt"
	"net/http"
	"os"
	"strings"
	"time"

	"github.com/gocolly/colly"
)

type Session struct {
	session *colly.Collector
	file    *os.File
	url     string
}

func (c *Session) Init() *colly.Collector {
	c.session = colly.NewCollector()

	c.session.AllowedDomains = []string{c.url}
	c.session.AllowURLRevisit = true
	// c.session.Async = true
	c.session.UserAgent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36"
	// extensions.RandomUserAgent(c.session)

	err := c.session.Limit(&colly.LimitRule{
		DomainGlob:  fmt.Sprintf("%s/*", c.url),
		Delay:       1 * time.Second,
		RandomDelay: 1 * time.Second,
		Parallelism: 5,
	})
	if err != nil {
		panic(err)
	}

	headers := map[string]string{
		"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36",
		"Host":       c.url,
		"Connection": "keep-alive",
		"Accept":     "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
	}

	c.session.OnRequest(func(r *colly.Request) {
		fmt.Println("Visiting: ", r.URL.String())
		for key, value := range headers {
			r.Headers.Add(key, value)
		}
	})

	c.url = fmt.Sprintf("http://%s", c.url)

	return c.session
}

func (c *Session) getCsrfToken() string {
	csrfToken := ""
	c.session.OnHTML("form input[name=\"csrf_token\"]", func(e *colly.HTMLElement) {
		csrfToken = e.Attr("value")
		fmt.Println("csrfToken: ", csrfToken)
	})

	err := c.session.Visit(fmt.Sprintf("%s/login", c.url))
	if err != nil {
		panic(err)
	}

	return csrfToken
}
func (c *Session) login(csrfToken string) {
	url := fmt.Sprintf("%s/login", c.url)

	err := c.session.Post(url, map[string]string{
		"username":   "qqq",
		"password":   "qqq",
		"csrf_token": csrfToken,
	})
	if err != nil {
		panic(err)
	}

	c.session.OnResponse(func(r *colly.Response) {
		if r.StatusCode != 200 {
			fmt.Println("访问失败: ", url)
		}
		fmt.Println(r.StatusCode)
	})

	err = c.session.Visit(url)
	if err != nil {
		panic(err)
	}
}
func (c *Session) cookieLogin() {
	// fmt.Println(c.session.Cookies(c.url))

	c.session.OnRequest(func(r *colly.Request) {
		// cookies := setCookieRaw("session=eyJjc3JmX3Rva2VuIjoiR3doU0FqTG5RV3pkTkp2RE1vS1lCZmdPeFJ0VFZGaVVFQ2xYYmtadW1yYVBzeXFwY2VISSIsInVzZXJuYW1lIjoicXFxIn0.EmHo_w.pMG9x7Vdwd2INAw1O25NLw6saRk")
		cookies := []*http.Cookie{
			{
				Name:  "session",
				Value: "eyJjc3JmX3Rva2VuIjoiR3doU0FqTG5RV3pkTkp2RE1vS1lCZmdPeFJ0VFZGaVVFQ2xYYmtadW1yYVBzeXFwY2VISSIsInVzZXJuYW1lIjoicXFxIn0.EmH1iA.wk6GNffYi6R2vaBhZPLYLBZfwpY",
			},
		}
		err := c.session.SetCookies(c.url, cookies)
		if err != nil {
			panic(err)
		}
	})
}
func (c *Session) getIndex() {
	c.session.OnHTML(".row.header-box .col-md-4 p a", func(e *colly.HTMLElement) {
		fmt.Println("Logout flag: ", e.Text)
	})
	c.session.OnResponse(func(r *colly.Response) {
		if r.StatusCode != 200 {
			fmt.Println("访问失败: ", c.url)
		}
		fmt.Println(string(r.Body))
	})

	err := c.session.Visit(c.url)
	if err != nil {
		panic(err)
	}
}

func setCookieRaw(cookieRaw string) []*http.Cookie {
	var cookies []*http.Cookie

	items := strings.Split(cookieRaw, "; ")
	for _, item := range items {
		keyValue := strings.Split(item, "=")
		name := keyValue[0]
		values := keyValue[1:]

		cookies = append(cookies, &http.Cookie{
			Name:  name,
			Value: strings.Join(values, "="),
		})
	}

	return cookies
}
